package core

import (
	"gitee.com/hongzhaomin/gspring/iface"
	"gitee.com/hongzhaomin/gspring/tools"
	"reflect"
)

func NewConfigurableBeanDefinition(beanName string, parent iface.BeanDefinition, methodInfo *iface.CreateBeanMethodInfo) *ConfigurableBeanDefinition {
	cfgBD := new(ConfigurableBeanDefinition)
	cfgBD.SetBeanName(beanName).
		SetParent(parent).
		SetCreateBeanMethodInfo(methodInfo)
	return cfgBD
}

// ===========================================================================
// ======================= ConfigurableBeanDefinition ========================
// ===========================================================================
var _ iface.BeanDefinition = (*ConfigurableBeanDefinition)(nil)

type ConfigurableBeanDefinition struct {
	// 继承的父类对象
	DefaultBeanDefinition

	// 定义创建对象的方法的 配置类（Configuration类）自身的bean定义信息
	// 后面创建对象需要反射调用方法，那么调用方法的对象，就是它了
	parent iface.BeanDefinition

	// 解析出来的配置bean里面定义的创建对象的方法信息
	// 后面创建对象的时候会根据方法信息反射调用方法创建一个gspring管理的对象
	methodInfo *iface.CreateBeanMethodInfo
}

func (my *ConfigurableBeanDefinition) GetParent() iface.BeanDefinition {
	return my.parent
}

func (my *ConfigurableBeanDefinition) SetParent(parent iface.BeanDefinition) iface.BeanDefinition {
	tools.Assert().NotNil(parent, "parent must not be <nil>")
	my.parent = parent
	return my
}

func (my *ConfigurableBeanDefinition) SetBeanName(beanName string) iface.BeanDefinition {
	my.DefaultBeanDefinition.SetBeanName(beanName)
	return my
}

func (my *ConfigurableBeanDefinition) SetObjRefType(reflect.Type) iface.BeanDefinition {
	panic("ConfigurableBeanDefinition 不支持设置bean类型")
}

func (my *ConfigurableBeanDefinition) GetObjRefType() reflect.Type {
	return my.methodInfo.RtDeclaredReturnBean
}

func (my *ConfigurableBeanDefinition) GetObjRefTypeToPtr() reflect.Type {
	rt := my.methodInfo.RtDeclaredReturnBean
	if rt.Kind() == reflect.Ptr {
		return rt
	}
	return reflect.PointerTo(my.GetObjRefType())
}

func (my *ConfigurableBeanDefinition) GetCreateBeanMethodInfo() *iface.CreateBeanMethodInfo {
	return my.methodInfo
}

func (my *ConfigurableBeanDefinition) SetCreateBeanMethodInfo(info *iface.CreateBeanMethodInfo) iface.BeanDefinition {
	tools.Assert().NotNil(info, "methodInfo must not be <nil>")
	info.Check()
	my.methodInfo = info
	return my
}
